package com.base.dao;

import java.io.Serializable;
import java.sql.Connection;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.base.pagination.Condition;
import com.base.pagination.Page;
import com.base.utils.LevelCodeGenerator;

public class BaseDaoImpl extends HibernateDaoSupport implements IBaseDao {
	/**
	 * 数据源
	 */
	private DataSource dataSource;
	private static final Logger logger = Logger.getLogger(BaseDaoImpl.class);

	/** 统计指定类的所有持久化对象 */
	public int countAll(String clazz) {
		final String hql = "select count(*) from "+clazz+ " as a";
		Long count = (Long)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql);
				query.setMaxResults(1);
				return query.uniqueResult();
			}
		});	
		return count.intValue();
	}

	/** 统计指定类的查询结果 */
	public int countQuery(String hql) {
		final String counthql = hql;
		Long count = (Long)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(counthql);
				return query.uniqueResult();
			}
		});
		return count.intValue();
	}

	/** 删除指定ID的持久化对象 */
	public void delById(Class clazz,Serializable id) {
		getHibernateTemplate().delete(getHibernateTemplate().load(clazz, id));			
	}

	/** 装载指定类的所有持久化对象 */
	public List listAll(String clazz) {
		return getHibernateTemplate().find("from "+clazz+" as a order by a.id desc");
	}
	
	/** 分页装载指定类的所有持久化对象 */
	public List listAll(String clazz, int pageNo, int pageSize) {
		final int pNo = pageNo;
		final int pSize = pageSize;
		final String hql = "from "+clazz+ " as a order by a.id desc";
		List list = getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql);
				query.setMaxResults(pSize);
				query.setFirstResult((pNo-1)*pSize);
				List result = query.list();
				if (!Hibernate.isInitialized(result))Hibernate.initialize(result);
				return result;
			}
		});	
		return list;
	}
	
	/** 加载指定ID的持久化对象 */
	public Object loadById(Class clazz,Serializable id) {
		return getHibernateTemplate().get(clazz, id);
	}
	
	/**加载满足条件的持久化对象*/
	public Object loadObject(String hql) {
		final String hql1 = hql;
		Object obj = null;
		List list = getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql1);
				return query.list();
			}
		});			
		if(list.size()>0)obj=list.get(0);	
		return obj;
	}
	
	/** 查询指定类的满足条件的持久化对象 条件为占位符*/
	public Object loadObject(String hql, Object[] args) {
		final String hql1 = hql;
		List list = getHibernateTemplate().find(hql,args);
		if(list.size()>0)
			return list.get(0);
		else	
			return null;
	}
		

	/** 查询指定类的满足条件的持久化对象 */
	public List query(String hql) {
		final String hql1 = hql;
		return getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql1);
				return query.list();
			}
		});	
	}
	
	/** 查询指定类的满足条件的持久化对象 条件为占位符*/
	public List query(String hql, Object[] args) {
		return getHibernateTemplate().find(hql,args);
	}

	/** 分页查询指定类的满足条件的持久化对象 */
	public List query(String hql, int pageNo, int pageSize) {
		final int pNo = pageNo;
		final int pSize = pageSize;
		final String hql1 = hql;
		return getHibernateTemplate().executeFind(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql1);
				query.setMaxResults(pSize);
				query.setFirstResult((pNo-1)*pSize);
				List result = query.list();
				if (!Hibernate.isInitialized(result))Hibernate.initialize(result);
				return result;
			}
		});	
	}
	
	/** 保存指定的持久化对象 */
	public void save(Object obj){
		getHibernateTemplate().save(obj);
	}
	
	/** 保存或更新指定的持久化对象 */
	public void saveOrUpdate(Object obj) {
		getHibernateTemplate().saveOrUpdate(obj);
	}

	/** 条件更新数据 */
	public int update(String hql) {
		final String hql1 = hql; 
		return ((Integer)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws HibernateException{
				Query query = session.createQuery(hql1);
				return query.executeUpdate();
			}
		})).intValue();	
	}
	
	/** 更新数据 */
	public void updateObject(String objName, Object obj) {
		getHibernateTemplate().update(objName, obj);
	}
	
	/** 从连接池中取得一个JDBC连接 */
	public Connection getConnection() {
		return getHibernateTemplate().getSessionFactory().getCurrentSession().connection();
	}
	/**  通过hql语句检索数据库表中记录，但是结果集为托管状态，延迟加载会不起作用 */
	public List queryDetachedObjects(String p_hql) {
		List _list = getHibernateTemplate().find(p_hql);
		getHibernateTemplate().clear();
		return _list;
	}
	/** 通过ID检索数据库表中记录，但是结果为托管状态，延迟加载会不起作用 **/
	public Object queryDetachedById(Class p_obj, Serializable p_obj_id) {
		Object object = (Object) this.getHibernateTemplate().get(p_obj, p_obj_id);
		this.getHibernateTemplate().clear();
		return object;
	}
	/**  批量更新 **/
	public void bulkUpdate(String p_hql) {
		getHibernateTemplate().bulkUpdate(p_hql);
	}
	
	public Page pagedQuery(Condition p_condition) {
		int _pageNo = p_condition.getPageNo();
		int _pageSize = p_condition.getPageSize();
		long _totalCount = this.count(p_condition);
		if (_totalCount < 1)
			return new Page();
		int _startIndex = Page.getStartOfPage(_pageNo, _pageSize);

		// if startIndex >= totalCount then go to the last page
		if (_startIndex >= _totalCount) {
			return this.lastOfPagedQuery(p_condition);
		}
		Query _query = p_condition.getHibernateQuery(this.getSession());

		List _list = _query.setFirstResult(_startIndex).setMaxResults(_pageSize).list();

		return new Page(_startIndex, _totalCount, _pageSize, p_condition.getOrderByItem(), _list);
	}
	
	public Page lastOfPagedQuery(Condition condition) {
		long totalCount = this.count(condition);
		int pageNo;
		if (totalCount % condition.getPageSize() == 0)
			pageNo = new Long(totalCount / condition.getPageSize()).intValue();
		else
			pageNo = new Long(totalCount / condition.getPageSize() + 1)
					.intValue();
		condition.setPageNo(pageNo);
		return pagedQuery(condition);
	}
	
	/**  统计查询页数 **/
	private long count(Condition p_condition) {
		Query query = p_condition.getHibernateCountQuery(this.getSession());
		List countlist = query.list();

		long totalCount = ((Long) countlist.get(0)).longValue();
		return totalCount;
	}
	
	public void deleteObjects(Collection cols){
		getHibernateTemplate().deleteAll(cols);
		getHibernateTemplate().flush();

	}
	
	public String generator(int level, String codeRule, String prefix, String hqlString) throws Exception {
		String maxCode = (String) this.query(hqlString).get(0);
        return LevelCodeGenerator.generator(level, codeRule, prefix,maxCode);
	}
	
	public boolean checkRepeatObject(String hqlString) {
		List repeat = this.query(hqlString);
		if (repeat.size() > 0)
			return true;
		return false;
	}
	
	public void delete(Object p_obj) {
		getHibernateTemplate().delete(p_obj);
	}
	
	public void saveOrUpdateObjects(Collection p_cols) {
		getHibernateTemplate().saveOrUpdateAll(p_cols);
		getHibernateTemplate().flush();
	}
	
	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource source) {
		dataSource=source;
	}

	public void sessionClear() {
		this.getHibernateTemplate().flush();
		this.getHibernateTemplate().clear();
		
	}
	
	//父类HibernateDaoSupport注入sessionFactory的值
    @Resource(name = "sessionFactory")
    public void setSuperSessionFactory(SessionFactory sessionFactory)
    {
        super.setSessionFactory(sessionFactory);

    }

}